11 - Input Devices

Sensing a Magnetic Field with a Hall Sensor

This week was one of the few were I already knew what I would like to exactly do before the week started. As this topic is actually the last week with electronics, I already previously designed and manufactured a board for my final project that should be capable of reading the output of a Hall sensor. For this, I already had to pick a certain sensor, which I will connect to the board this week. This weeks's assignment were:

  • Group Assignment
    • Probe an input device's analog levels and digital signals
  • Individual Assignment
    • Measure something: Add a sensor to a microcontroller board that you have designed and read it

Group Assignment

For the group assignment, we had to probe an output of an input device. This should be done for one digital and one analog output. In this case, we did this only for one sensor module that supplies the user with an analog and a digital output, namely the same hall sensor, that I have been using for my individual assignment (see below).

In principle, we connected the break out board to a power supply via the power and ground pins of a microcontroller. Additionally, the digital as well as analog output of the module were joined with a digital and analog channel of an oscilloscope. With the latter the digital and analog outputs were measured while approaching and withdrawing the sensor with a magnet. Here, the analog output of the sensor was a true analog value which is depending on the pole of the magnet and its distance in all spatial directions. The sensitivity and by this the reaction of the sensor to the magnet can be increased and decreased by turning a potentiometer on the sensor's break out board.

The output of the digital pin was quite surprising as it actually is something like a PWM signal just not with a rectangular wave patter but rather a sawtooth pattern with curved edges. Have a look at the image to see the output.

The amplitude of the digital signal is about 3.9 V with a duty cycle of about 70.1% for a continuous pattern.

For the details on the group assignment, please refer to our group page. You can find it here.

Oscilloscope Showing the Digital Output

Individual Assignment

This week's task were simple for me as I already made a big effort in the electronics design. Here, I designed a PCB for my final project according to the external components I needed. For this, I had already researched and identified which components are the best to use with regards to availability. Hence, for this week, I already had a board and the input output devices, which are a hall sensor and a camera.

A Hall Sensor for Angle Measurements

The hall sensor I wanted to use is this one. Its purpose is to measure the strength of a magnetic field qualitatively. For my final project, the magnetic field is generated by a diametrical magnet that is mounted to the rotating shaft. By measuring the field strength, the angle of the rotation should be sensed.

However, to measure something with this sensor, I firstly had to establish a serial communication between the board and my computer, then take some preliminary measurements and lastly actually measure the strength of the magnetic field qualitatively.

Breakout Board with Hall Sensor (Black Box in the Top)

Establishing a Serial Communication

To allow for measuring something with the Hall sensor and actually display the readings, I need an output device, preferably a display that can show the readings. However, instead of connecting such a component directly to the board, I decided to let the board send the readings to the serial monitor of the Arduino IDE such that my computer can display the readings.

In order to establish a serial communication via UART, I firstly researched on how to program that with the Arduino IDE. Here, I specifically searched for a sketch that also allows me to specify the Rx and Tx pins as I did not know whether the they are already pre-configured. Here, I found this documentation where they used the SoftwareSerial library.

I copied the code from that website into a new Arduino sketch. Then, I only added a delay to send the message "100" every half of a second abd few lines to make an LED flash whenever a serial message is send. The pin definitions were set in accordance to the pinout that Arduino uses for referencing it as shown here. Next, I setup the Arduino IDE and connected the board to my computer via a programmer board and the UPDI pins as shown here. Lastly, I uploaded the Arduino sketch to the microcontroller. The code is shown below.

#include "SoftwareSerial.h"

// Declare and initialize UART pins
const int rx_pin = 4;
const int tx_pin = 5;

// Declare and initialize led pin
const int led_pin = 9;

// Create new serial with specified UART pins
SoftwareSerial mySerial(rx_pin , tx_pin);


void setup(){ 
	// Set the pin modes of UART pins
	pinMode(rx_pin, INPUT); // Receiving requires input
	pinMode(tx_pin, OUTPUT); // Transmitting requires output

	// Set led as output
	pinMode(led_pin, OUTPUT);

	// Start the serial communication at 9600 bits/sec
	mySerial.begin(9600);
}


void loop(){ 
	mySerial.println("100"); // Send the message "100"

	// Flash the LED
	digitalWrite(led_pin,HIGH);
	delay(100);
	digitalWrite(led_pin,LOW);

	// Wait some time (500ms in total)
	delay(400);
}

As I saw the built-in LED flashing, I continued with establishing a physical serial connection. Here, I firstly removed all connections from the board including the programmer board and secondly connected an FTDI module to the FTDI pins of the board. Then, I connected the FTDI module to my computer with a USB cable. This setup is shown in the following picture.

Connecting the Board to an FTDI Module

As soon as I had connected the FTDI module to my computer, the power LED turned on. Slightly later, the blue built-in LED on the board started to flash indicating whenever a serial message was sent.

Next, I wanted to open the serial monitor of the Arduino IDE by going to Tools > Serial Monitor. However, this gave me an error message that the board at the chosen COM is not available. Therefore, I changed the port to another one that appeared only after connecting the board to my computer via the FTDI module. This now allowed me to open the serial monitor. Lastly, I specified the baud rate to the 9600 bits per second that I defined in the sketch for serial communication.

As you can see in the video below, this communication worked flawless. The LED flashed every time a serial message was received.

Serial Communication with the Microcontroller Receiving "100" every Half Second on My Computer

Preliminary Measurements with a Hall Sensor

After having established a serial communication with the board, I wanted to achieve that the message consists of a reading of the sensor. For this, I slightly modified the code by adding a variable for the pin of the hall sensor and modifying the pin mode. Just before a serial message is sent, the analog value of the pin is measured and stored in the variable val which is then sent via the serial communication.

Next, I connected the board to my computer via the programmer board and UPDI connections again and set the port to the right COM. Then, I uploaded the modified sketch shown below.

#include "SoftwareSerial.h"

// Declare and initialize UART pins
const int rx_pin = 4;
const int tx_pin = 5;

// Declare and initialize led and hall sensor pin
const int led_pin = 9;
const int hall_pin = 8;

// Create new serial with specified UART pins
SoftwareSerial mySerial(rx_pin , tx_pin);


void setup(){ 
	// Set the pin modes of UART pins
	pinMode(rx_pin, INPUT); // Receiving requires input
	pinMode(tx_pin, OUTPUT); // Transmitting requires output

	// Set led as output
	pinMode(led_pin, OUTPUT);

	// Set sensor as input
	pinMode(hall_pin, INPUT);

	// Start the serial communication at 9600 bits/sec
	mySerial.begin(9600);
}


void loop(){ 
	// Read the analog value of the pin and send it via serial communication
	int val = analogRead(hall_pin);
	mySerial.println(val);

	// Flash the LED
	digitalWrite(led_pin,HIGH);
	delay(100);
	digitalWrite(led_pin,LOW);

	// Wait some time (500ms in total)
	delay(400);
}

After the upload, I disconnected the programmer board and connected the FTDI module to my computer. Next, I attached the Hall sensor to my board. For this, three cables are needed, one for VCC and the ground respectively and the last one for the data. This sensor offers two data connections. One of them is a digital output signal that switches between a high an low voltage level and by this senses whether there is a magnet close by or not. The other output signal is analog which also allows to estimate the magnetic field strength. Here, I chose the latter as this also allows to sense the orientation of a magnet as needed for my final project.

The PCB Connected to an FTDI Module (Bottom) and a Hall Sensor (Top)

In the Arduino IDE, I again changed the port and opened the serial plotter via Tools > Serial Plotter. Then, I used a magnet that I found on a whiteboard and approached the hall sensor with one flat side and consecutively with the opposite side as shown in the video below.

Moving the Magnet

As shown in the image below from the serial plotter, the baseline of the sensor without any magnet close to it, the sensor's reading is at about 550. When one side of the magnet approaches the sensor, the measurements increase drastically. Vice versa, if the other side of the magnet, i.e. the opposite polarization, approaches the sensor, the measurements decrease, however to not such a big extent as the peak. This might be due to the cap on the magnet, that prevents me to approach the magnet as closely as with the other side.

Output of the Hall Sensor with Low Time-Resolution

Measuring the Strength of an Magnetic Field Qualitatively

After I successfully tested the sketch and the circuit's connection, I continued with a more sophisticated program. Here, I aimed for a higher time-wise resolution. Therefore, I deleted everything regarding the LED and decreased the pause in the end of the loop.

To upload the modified sketch as shown below, I again connected the board via a programmer board and UPDI pins. Then, I selected the right port in the Arduino IDE and uploaded the program.

#include "SoftwareSerial.h"

// Declare and initialize UART pins
const int rx_pin = 4;
const int tx_pin = 5;

// Declare and initialize hall sensor pin
const int hall_pin = 8;

// Create new serial with specified UART pins
SoftwareSerial mySerial(rx_pin , tx_pin);


void setup(){ 
	// Set the pin modes of UART pins
	pinMode(rx_pin, INPUT); // Receiving requires input
	pinMode(tx_pin, OUTPUT); // Transmitting requires output

	// Set sensor as input
	pinMode(hall_pin, INPUT);

	// Start the serial communication at 9600 bits/sec
	mySerial.begin(9600);
}


void loop(){ 
	// Read the analog value of the pin and send it via serial communication
	int val = analogRead(hall_pin);
	mySerial.println(val);

	// Add a small pause of 50ms
	delay(50);
}

Once the upload was complete, I disconnected the programmer board, connected the FTDI module to the PCB and my computer and selected the right port in the Arduino IDE. Lastly, I opened the serial plotter again and repeated moving the magnet to the sensor, first facing the one side and consecutively the other side.

As you can see in the image of the plotter below, many more measurements were taken while the magnet was moved in approximately the same speed. This also allows to see more details on the exact movement.

Output of the Hall Sensor with High Time-Resolution

Angle Measurements with a Hall Sensor

With the setup above, I investigated the functional principles of the sensor. In the future, for my final project, I would like to use this sensor for angle measurements. Here, the magnet should be mounted to a rotating shaft and by this rotate according to the shaft. The sensor should then measure the magnetic field strength. With this, angle measurements should be possible.

To make this possible, the magnet must be oriented such that a rotation should induce a change of the magnetic field strength. Here, the easiest would be to use a diametric magnet, where each pole consist of an extruded semicircle as shown in the image.

Diametric Magnet with Semicircular Poles

To finish this part with appropriate angle measurements, I bought diametric magnets. Next, I had to design and manufacture a magnet holder to hold the magnet at the end of the shaft. With this, I was then able to record the angle of a shaft that is continuously rotated by the motor.

Design and Manufacturing of the Magnet Holder

The magnet holder was designed in Fusion 360. I started by drawing a ring on the XY plane with an inner diameter of 10 mm, i.e. the outer diameter of the diametric magnet as well as the shaft, plus a tolerance of 0.4 mm. The thickness of the ring was set to be 2.5 mm. I extruded it by 23 mm and closed one of the ends with a 10 mm extrusion. Next, I drew another ring on the open end of the structure with the same inner diameter and a wall thickness of 10 mm. This ring was extruded by another 10 mm generating the raw structure of the magnet holder.

Next, to keep the magnet holder and the magnet itself attached to the shaft, I made rectangular inserts for nuts and orthogonally to it circular inserts for the according bolts. The bolts can be used as set screws to tighten the 3D printed part against the shaft and the magnet.

Lastly, I added a chamfer to between the two rings of the raw structure to make a smoother finish.

Raw Structure of the Magnet Holder

Added Nut and Bolt Inserts

Added Chamfer

From Fusion, this design was exported as an .stl file which was imported into the software Ultimaker Cura. Here, the machine code for an Ultimaker S5 was generated using the profile "Normal - 0.15 mm" without any supports and black Ultimaker PLA as a material. The generated file was brought to the 3D printer via a flash drive where it was started by selecting the file and confirming the start.

Programming Motor Rotations and Angle Measurements

Next, I programmed the board with the setup shown above. The code that I uploaded to the board is basically the same as in the previous section but also performs a motor step right before reading the analog value of the hall sensor and sending the reading to my computer via the serial communication. However, the sensor readings are averaged over ten measurements.

#include "SoftwareSerial.h"

// Declare and initialize UART pins
const int rx_pin = 4;
const int tx_pin = 5;

// Declare and initialize hall sensor pin
const int hall_pin = 8;

// Define pin numbers for motor driver
const int dirPin = 1; // direction
const int stepPin = 2; // step
const int enaPin = 3; // enable

// set number of steps that the motor should rotate
const int steps = 16*200*2; 

int sum = 0;

// Create new serial with specified UART pins
SoftwareSerial mySerial(rx_pin , tx_pin);

void setup() {
	// Set the pin modes of UART pins
	pinMode(rx_pin, INPUT); // Receiving requires input
	pinMode(tx_pin, OUTPUT); // Transmitting requires output

	// Set sensor as input
	pinMode(hall_pin, INPUT);

	// Start the serial communication at 9600 bits/sec
	mySerial.begin(9600);
	
	// Define all pins for motor driver as output
	pinMode(stepPin,OUTPUT);
	pinMode(dirPin,OUTPUT);
	pinMode(enaPin,OUTPUT);

// Enable the motor driver
	digitalWrite(enaPin,LOW);
	digitalWrite(dirPin,HIGH); // Set the rotation to one particular direction
}

void loop() {
	// Perform a certain number of steps
	for(int x = 0; x < steps; x++) {
		// Generate a pulse
		digitalWrite(stepPin,HIGH);
		delayMicroseconds(700);
		digitalWrite(stepPin,LOW);
		delayMicroseconds(700);
		
		// Read the analog value of the pin and send it via serial communication
		int val = analogRead(hall_pin);
		// Average the readings over ten points
		if (x%10 == 0){
			mySerial.println(sum/10);
			sum = 0;
		}
		else {
			sum = sum + val;
		}
	}
}
Setup for Angle Measurements

The setup to measure the angle that is generated by a continuous rotation of a motor consist also of the serial connection (see above). Additionally, the Hall sensor is connected to it (see above). In addition however, the stepper motor and a bench power supply is connected as shown in the assignment on output devices. Lastly, I attached the magnet holder with a magnet to the motor shaft. A photo of the complete setup including the programmer board is shown below.

During the measurements, I tried to hold my hand as steady as possible to keep a constant distant to the magnet.

Setup for Angle Measurements

Results of Angle Measurements

Once everything was setup, I set the bench power supply to 24 V and a load-dependent current. As soon as the power was supplied to the motor, it started rotating as shown in the video.

Motor Rotating During the Angle Measurements

In addition, I opened the serial plotter via Tools > Serial Plotter which showed the sensor readings below. The deviations of the slope in the readings correspond to an off-centric rotation of the magnet as the magnet holder is designed for a 10 mm shaft.

Results of Measuring the Angle of the Rotation

Recording Videos with the Raspberry Pi Camera

In addition to the hall sensor as an input device, a camera is needed for my final project. During the rotations of the shaft suspending the glass plate, the camera rotates with the glass plate and records videos of it. However, the video recording should happen upon a signal from the main board. To accomplish this, I firstly setup the camera, i.e. a Raspberry Pi 4 model B with 4 GB RAM. Then, I connect the camera module and lens and lastly, I programmed it to record videos. For the lens, I chose the 6 mm lens as it allows for a relatively wide angle for the field of view. With this, the camera does not need to be mounted so far away from the glass plate, i.e. the object it should record.

Setup of Headless Raspberry Pi

A Raspberry Pi (RaspPi) is a small computer already. However, often and also in my case, only the board is bought without any display, keyboard or other input devices. This is called a headless RaspPi. To to the lack of the input devices to control it, the setup is very much different than just supplying power and waiting for it to boot. In contrast, I used the Raspberry Pi Imager software. This allows to install the OS with settings like internet connections by saving it to an microSD card. By inserting it into the SD card slot on the RaspPi, it boots using this partition. The remaining setup or programming can then be done via an internet connection.

Raspberry Pi Imager Software

After downloading the software and inserting an SD card into a reader on my computer, I opened the software. Here, I selected the Raspberry Pi 4 as a model, the Raspberry Pi OS (64-bit) as the operating system and lastly the inserted SD card as the storage device.

Upon pressing "Next", the user is presented with multiple options, where I selected "EDIT SETTINGS". In the "General" tab, I set a username and password and configured a wireless LAN connection with desired inputs. As the WiFi, I used a mobile hotspot of my phone to allow for using the headless RaspPi at different locations as well. Lastly, enabled an SSH connection in the "Services" tab.

Edit Settings of OS Customization

After pressing "SAVE" and confirming to write the data to the storage device, I had to wait for finishing the writing and the verification. Once, that was done, I ejected the microSD card, inserted it into the SD card reader of the RaspPi. After supplying power to it, it booted and automatically connected to the mobile hotspot of my phone. In the hotspot settings on my phone, I was able to see which IP address is used by the RaspPi.

To establish an SSH connection, I firstly downloaded PuTTY. After opening, I typed in the IP address of the RaspPi as the host name, selected the port number 22 and clicked "Open". This lead to a new window showing the command terminal of the RaspPi.

PuTTY Software

After inputting the username and password which I specified in the Imager software, I typed the command

sudo raspi-config

into the terminal to open the configurations of the RaspPi. In the main menu, I navigated to the "Interfacing Options" using the arrow keys and pressed enter. Next, I navigated to "VNC" and pressed enter again. Then, I was asked if I would like to enable the VNC server. After selecting "Yes" and entering, it showed a confirmation message that the server was enabled.

Main Menu of RaspPi Configurations

Interfacing Options of RaspPi Configurations

Now, I was able to remotely access the RaspPi with graphical content. For this, I used the software RealVNC Viewer. After typing in the IP address of the RaspPi and inputting the correct username and password, I was able to see the desktop of the RaspPi on my computer and controlling it remotely via this window.

Desktop of RaspPi

Attaching the Camera Module

From the hardware's perspective, I had to connect the camera lens to the camera module and then the latter to the board or the RaspPi. For this, I firstly shutdown the RaspPi. Next, I attached the camera lense to the camera module. This was easily done by rotating the lense into the module like a screw into a nut. I stopped after the connection was relatively tight such that it does not loosen anymore.

Then, I connected the camera module to the RaspPi with the ribbon cable attached to it. The board already has a camera serial interface (CSI) which firstly needs to be opened, then the ribbon cable can be inserted and lastly, the connector has to be closed again. This enabled a secure connection between camera and RaspPi.

Camera Module and Lense Attached to the Raspberry Pi

Programming to Record Videos Upon a Signal

As a next step, I programmed the RaspPi to record videos upon a signal. For this, the first step was to program it to record videos for a certain duration, secondly to make it react to a signal and lastly merge the two scripts to start and stop the video recording upon the signal.

Recording Videos

To program the RaspPi to record videos, firstly a new file has to be created. For this, I right-clicked on the desktop and chose to create a new file. I named it with a the ".py" ending. Thus, it already implied that it is a python script and therfore, when opening the file with a double-click, the file opens in a programming environment named "Thonny".

Next, I searched online on how to program the RaspPi to record videos. Here, I found the Picamera2 library and its datasheet. In there, there is a small programming example on how to record videos shown in the following.

from picamera2 import Picamera2
picam2 = Picamera2()
picam2.start_and_record_video("test.mp4", duration=5)

Fortunately, the Picamera2 package was already pre-installed on the RaspPi and therefore this script was working well. However, I wanted more control on the resolution, on the file ending as well as start and stop functions. I read through more of the manual and eventually came up with the following script:

from picamera2 import Picamera2
from picamera2.encoders import H264Encoder
from picamera2.outputs import FfmpegOutput
import time

duration = 2 # Duration of video recording in seconds

picam2 = Picamera2() # Create camera instance
video_config = picam2.create_video_configuration(main={"size": (1700, 1275)}) # Configure resolution
picam2.configure(video_config) # Add configurations to camera (with default 30fps)
h264encoder = H264Encoder() # Create encoder


picam2.start_recording(h264encoder, FfmpegOutput("video.mp4"))
print("Recording...")

time.sleep(duration) # Wait for a certain amount of time before stopping the recording

picam2.stop_recording() # Stop recording
print("Video recording has stopped!")

Upon running this script, it creates a video on the desktop which is 2 s long with the defined resolution and 30 frames per second.

Recording a Two Second Video

Reacting to a Signal

After I was able to record videos, I had to make the RaspPi react to a signal. As a signal, I choose to simply use a high and low voltage level as this is able to be transmitted via relatively long cables, approximately longer than 0.5 m. Therefore, this can be sensed with various general-purpose input/output (GPIO) pins.

As a first step of programming to sense a digital input at a GPIO pin, I found this tutorial. Apparently, different naming conventions can be used. In this case, I decided to go for the pin number 11 which can be addressed with the number 17. The numbering, broadcom (BCM) numbering and the purpose of the GPIOs of the Raspberry Pi 4 can be seen in the image.

Pinout with BCM Numbering of Raspberry Pi 4

Therefore, I wrote the following lines of code into a new Python file.

import RPi.GPIO as GPIO

pin = 17 # declare pin with number 11
GPIO.setmode(GPIO.BCM) # use BCM numbers to address pins
GPIO.setup(pin, GPIO.IN) # set mode of pin to input

These lines simply setup the GPIO. Next, the state has to be sensed. For this, I searched online and found this forum. Here, they sense the state with simply using the GPIO.input() function. It is "True" or "1" if the pin is at a high voltage level and "False" or "0" if it is low.

In total, I therefore programmed the following script:

import RPi.GPIO as GPIO
import time

pin = 17 # declare pin with number 11

GPIO.setmode(GPIO.BCM) # use BCM numbers to address pins
GPIO.setup(pin, GPIO.IN) # set mode of pin to input

while True:
	state = GPIO.input(pin)
	if state == 1:
		print("High")
	else:
		print("Low")
	time.sleep(0.5)

Then, connected jumper wires to a 5 V and ground pin as well as to the pin number 11 (BCM: 17). In the photo below, one jumper cable is missing, namely the ground pin.

RaspPi With Jumper Cables on the 5 V Pin (Orange) and Pin 17 (Purple), Ground Jumper Cable is Missing

Next, I started the script and connected the jumper of pin 11 alternatingly to the 5 V and ground jumper cable. By this, I switched the state of it from a high to a low voltage level. If the GPIO pin was connected to 5 V, "High" was printed, otherwise "Low".

Sensing High and Low State of GPIO

Recoding Videos Upon Signal

Lastly, I merged the two scripts into one. The setup of the camera and for teh GPIO was placed in the beginning and the functions for the start and stop of the recording in the if statements. Therefore, recording a video is only started if the pin is at a high voltage level and stopped at a low voltage level. Additionally, to avoid re-starting the recording, a boolean called "recording" is used which keeps track of whether the recording is already running or not. This is the complete code:

import RPi.GPIO as GPIO
from picamera2 import MappedArray, Picamera2
from picamera2.encoders import H264Encoder
from picamera2.outputs import FfmpegOutput
import time

# Setup of GPIO
pin = 17 # declare pin with number 11
GPIO.setmode(GPIO.BCM) # use BCM numbers to address pins
GPIO.setup(pin, GPIO.IN) # set mode of pin to input

# Create configurations for camera instance
picam2 = Picamera2() # Create camera instance
video_config = picam2.create_video_configuration(main={"size": (1700, 1275)}) # Configure resolution in 3:2 ratio
picam2.configure(video_config) # Add configurations to camera (with default 30fps)
h264encoder = H264Encoder(bitrate=17000000) # Create encoder
				
recording = False # Boolean to keep track of recording

while True:
	state = GPIO.input(pin)
	if state == 1 and not recording: 

		# Start recording
		picam2.start_recording(h264encoder, FfmpegOutput("video.mp4"))

		print("Video recording started")
		recording = True # Store information that recording in progress

	
	elif state == 0 and recording:
		picam2.stop_recording()
		print("Video recording terminated")

		recording = False  # Store information that no recording in progress

	time.sleep(0.01)

Later, I also added a destination for storing the video with a timestamp. For this, I need to import the "os" library and added the folderpath, a foldername and filename. The following code was placed just below the imports.

import os

# Set location and foldername (date)
foldername = time.strftime("%Y-%m-%d/", time.localtime())
folderpath = '/home/blackberry/Videos/' + foldername
if not os.path.exists(folderpath):
	os.makedirs(folderpath)

Additionally, the code below was placed right before starting the recording of the video.

filename = folderpath + '/' + \
	time.strftime("%H-%M-%S_", time.localtime())  + \
	str((int(time.time() * 1000)) %1000).zfill(3) + '.mp4'

Due to this part, the part FfmpegOutput("video.mp4") of the line when starting the recording can be replaced with FfmpegOutput(filename). In total, a folder at a destination specified in the folderpath variable with the current date as the name is created. In there, a file is created with the current time as the name. Therefore, new videos do not replace the old ones but all are saved.

Lastly, I added a timestamp to each frame to have the information and be able to synchronize the video recordings with the angle measurements for my final project.

import cv2
from datetime import datetime

def apply_timestamp(request):
	# Set configuration of timestamp
	colour = (255, 255, 255)
	origin = (0, 30)
	font = cv2.FONT_HERSHEY_SIMPLEX
	scale = 1
	thickness = 2
	curr_time = datetime.now()
	timestamp = curr_time.strftime('%Y-%m-%d %H:%M:%S.%f')
	# Place timestamp on frames
	with MappedArray(request, "main") as m:
		cv2.putText(m.array, timestamp, origin, font, scale, colour, thickness)
	
picam2 = Picamera2() # Create camera instance
picam2.pre_callback = apply_timestamp

I again tested the complete code, which is available in the downloads, by using the same setup as for the GPIO script. In total, a video was created anytime the pin was newly connected to the 5 V pin and terminated if it was connected to the ground pin. Here, it also must be noted that I was not able to switch the connections quickly enough and therefore, sometimes videos were created and terminated when no connection was present. This is due to the floating of the pin. Nevertheless, it proved that the script was working correctly.

Recording Videos in High and Terminating in Low Voltage Phases

Source Code for Download